package com.laolang.shop.modules.auth.filter;

import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.laolang.shop.common.core.domain.SimpleAjax;
import com.laolang.shop.common.core.util.PrintJsonWriter;
import com.laolang.shop.modules.auth.config.JwtProperty;
import com.laolang.shop.modules.auth.entity.LoginUser;
import com.laolang.shop.modules.auth.entity.TokenUser;
import com.laolang.shop.modules.auth.util.JwtTokenUtil;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;

/**
 * @author khlbat
 * @version 1.0
 * @date 2020/11/1 20:46
 */
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    private final JwtProperty jwtProperty;

    private final JwtTokenUtil jwtTokenUtil;

    private final AuthenticationManager authenticationManager;


    public JwtAuthenticationFilter(JwtProperty jwtProperty, JwtTokenUtil jwtTokenUtil, AuthenticationManager authenticationManager) {
        this.jwtProperty = jwtProperty;
        this.jwtTokenUtil = jwtTokenUtil;
        this.authenticationManager = authenticationManager;
        super.setFilterProcessesUrl("/auth/login");
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        try {
            LoginUser loginUser = new ObjectMapper().readValue(request.getInputStream(), LoginUser.class);
            if (null == loginUser) {
                throw new UsernameNotFoundException("该手机号未注册");
            }
            return authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(loginUser.getPhone(), loginUser.getPwd(), new ArrayList<>())
            );
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
        TokenUser tokenUser = (TokenUser) authResult.getPrincipal();
        String token = jwtTokenUtil.createToken(tokenUser);
        response.setHeader(jwtProperty.getTokenKey(), token);
        response.setHeader("Access-Control-Expose-Headers", jwtProperty.getHeader());
        // PrintJsonWriter.printJson(response, SimpleAjax.ok());
        response.setContentType("application/json;charset=utf-8");
        //setContentType与setCharacterEncoding的顺序不能调换，否则还是无法解决中文乱码的问题
        response.setCharacterEncoding("UTF-8");
        PrintWriter out = response.getWriter();
        SimpleAjax<String> ajax = SimpleAjax.<String>ok().setBody(token);
        String json = JSONUtil.toJsonStr(ajax);
        out.write(json);
    }

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
        PrintJsonWriter.printJson(response, SimpleAjax.failed().setMsg(failed.getMessage()));
    }
}
